#include <map>
#include <iostream>
#include <string>
#include <stdlib.h>
#include "comando.h"

#ifndef CMDFOR_H
#define CMDFOR_H

using namespace std;
class Cmd_For : public Comando {
	private:
		string variavel, criterio, valor_criterio;
		int linha_padrao, linha_saida;
		int v1, v2;
		bool devo_parar() {
			if (criterio == "<")
				if (v1 < v2)
					return false;
			if (criterio == ">") 
				if (v1 > v2) 
					return false;
			else if (criterio == "<=")
				if (v1 <= v2)
					return false;
			else if (criterio == ">=")
				if (v1 >= v2)
					return false;
			else if (criterio == "==")
				if (v1 != v2)
					return false;
			else if (criterio == "!=")
				if (v1 == v2)
					return false;
			return true;
		}
		void define_valores() {
			//define valor de v1
			//v1 é o valor do i do for
			string aux=memoria->find(variavel)->second;
			v1=stoi(aux);
			//define valor de v2, verifica se v2 é outra variavel, atributo de variavel ou um valor numerico
			bool numerico=true;
			for (int i=0; i<valor_criterio.size(); i++)
				if (!isdigit(valor_criterio[i]))
					numerico=false;
			if (numerico) 
				v2=stoi(valor_criterio);
			else {
				//o valor de criterio é uma variavel, agora deseja-se verificar se é um tamanho de uma palavra ou somente uma variavel
				if (valor_criterio.find(".length")==-1) { //é somente variavel
					aux=memoria->find(valor_criterio)->second;
					v2=stoi(aux);
				}
				else {//é tamanho de uma palavra
					aux=memoria->find(valor_criterio.substr(0, valor_criterio.find(".length")))->second;
					v2=aux.size();
				}
			}
		}
	public:
		Cmd_For(map<string,string> *memoria, int pc, string variavel, string criterio, string valor_criterio, int linha_padrao) : Comando (memoria, pc) {
			this->variavel=variavel;
			this->criterio=criterio;
			this->valor_criterio=valor_criterio;
			this->linha_padrao=linha_padrao;
		}
	
		int get_pc() {
			return pc;
		}
	
		int get_linha_padrao() {
			return linha_padrao;
		}
		
		void set_linha_saida(int linha_saida) {
			this->linha_saida=linha_saida;
		}

		virtual int executar() {
			define_valores();
			if (devo_parar())
				return linha_saida;
			return linha_padrao;
		}
};
#endif
